/******************* (C) COPYRIGHT 2022 CHU WEI TENG ***********************************************
**
**------------------ File Info ---------------------------------------------------------------------
** File name:      dwin_widget.c
** modified Date:  2022-05-10
** Last Version:   V1.0
** Descriptions: 
** 
**------------------ Modfication  log --------------------------------------------------------------
** Date       Who            Rev        Comments
----------------------------------------------------------------------------------------------------
   22/05/10  chuwt@qq.com    V1.00      created

****************************************************************************************************/
#include <string.h>
#include "dwin_adapt.h"
#include "dwin_widget.h"
#include "dwin_trans.h"

/* Private define----------------------------------------------------------------------------------*/

/* Private typedef---------------------------------------------------------------------------------*/

/* Private variables-------------------------------------------------------------------------------*/

/* public function---------------------------------------------------------------------------------*/

dwin_widget_t * dwin_widget_create(dwin_widget_t* parent, dwin_widget_vtable_t* vtable, uint16_t ex_size)
{
    return_value_if_fail(vtable, NULL);
 
    dwin_widget_t* widget = dwin_malloc(vtable->obj_size); 
    
    if (widget != NULL)
    {
        memset(widget, 0, vtable->obj_size);
        
        if (parent != NULL)
        {    
            widget->parent = parent;    
        }
        widget->vt = vtable;
        
        if (ex_size != 0)
        {
            widget->data = dwin_malloc(ex_size);
        
            if (widget->data != NULL)
            {
                memset(widget->data, 0, ex_size);
            }
            else
            {
                dwin_free(widget);
                widget = NULL;
            }
        }
    }
    return widget;
}

ret_t dwin_widget_free(dwin_widget_t* widget)
{
    return RET_OK;
}

ret_t dwin_widget_hide(dwin_widget_t* widget, uint8_t is_hide)
{
    return_value_if_fail(widget, RET_BAD_PARAMS);
    ret_t    result = RET_OK;
    uint16_t hide = 0xFF00;
    
    if (is_hide)
    {
        if (widget->active)
        {
            widget->active = 0;
            hide = DWIN_SWAPS(hide);
            result = dwin_var_write(widget->attr, &hide, 1);
        }
    }
    else
    {
        if (!widget->active)
        {
            widget->active = 1;
            hide = DWIN_SWAPS(widget->addr);
            result = dwin_var_write(widget->attr, &hide, 1);
        }
    }
    return result;
}

ret_t dwin_widget_change_color(dwin_widget_t* widget, uint16_t color)
{
    return_value_if_fail(widget, RET_BAD_PARAMS);
    ret_t    result = RET_OK;
    
    color = DWIN_SWAPS(color);
    result = dwin_var_write(widget->attr + 3, &color, 1);

    return result;
}

ret_t dwin_widget_write(dwin_widget_t* widget)
{
    return_value_if_fail(widget, RET_BAD_PARAMS);
    return_value_if_fail(widget->active, RET_OK);
    ret_t  result = RET_FAIL;

    switch(widget->widget_type)
    {
        case DWIN_EDIT:
        case DWIN_LABEL:
        {
            switch(widget->size)
            {
                case 2:
                {   
                    uint16_t word = 0;
                    memcpy(&word, widget->data, 2);
                    word = DWIN_SWAPS(word);
                    result = dwin_var_write(widget->addr, &word, 1);
                }break;

                case 4:
                {
                    uint32_t dword = 0;
                    memcpy(&dword, widget->data, 4);
                    dword = DWIN_SWAPL(dword);
                    result = dwin_var_write(widget->addr, &dword, 2);
                }break;

                case 8:
                {
                    uint64_t qword = 0;
                    memcpy(&qword, widget->data, 8);
                    qword = DWIN_SWAPLL(qword);
                    result = dwin_var_write(widget->addr, &qword, 4);
                }break;
            }
        }break;

        case DWIN_EDIT_GBK:
        case DWIN_LABEL_GBK:
        {
            char gbk[GBK_MAX_CNT] = {0};
            memcpy(gbk, widget->data, widget->size);
            uint8_t  len = strnlen(gbk, widget->size);
            memset(&gbk[len], 0xFF, widget->size - len);
            
            result = dwin_var_write(widget->addr, gbk, widget->size >> 1);

        }break;

        default : break;
    }

    return result;
}

ret_t dwin_multi_widget_write(dwin_widget_t** widget_arry, uint8_t count)
{
    return_value_if_fail(widget_arry, RET_BAD_PARAMS);

    ret_t          result = RET_FAIL;
    uint8_t        buff[PACK_DATA_SIZE] = {0};     
    uint8_t        len = 0; 
    dwin_widget_t* head = *widget_arry;

    for (uint8_t i = 0; i < count && len < sizeof(buff); i++)
    {
        dwin_widget_t* widget = *widget_arry++;

        switch(widget->widget_type)
        {
            case DWIN_EDIT:
            case DWIN_LABEL:
            {
                switch(widget->size)
                {
                    case 2:
                    {   
                        uint16_t word = 0;
                        memcpy(&word, widget->data, widget->size);
                        word = DWIN_SWAPS(word);
                        memcpy(&buff[len], &word, widget->size);
                        len += widget->size;
                    }break;

                    case 4:
                    {
                        uint32_t dword = 0;
                        memcpy(&dword, widget->data, widget->size);
                        dword = DWIN_SWAPL(dword);
                        memcpy(&buff[len], &dword, widget->size);
                        len += widget->size;
                    }break;

                    case 8:
                    {
                        uint64_t qword = 0;
                        memcpy(&qword, widget->data, widget->size);
                        qword = DWIN_SWAPLL(qword);
                        memcpy(&buff[len], &qword, widget->size);
                        len += widget->size;
                    }break;
                    
                    default : break;
                }
            
            }break;
            
            case DWIN_EDIT_GBK:
            case DWIN_LABEL_GBK:
            {
                char gbk[GBK_MAX_CNT] = {0};
                memcpy(gbk, widget->data, widget->size);
                uint8_t gbk_len = strnlen(gbk, widget->size);
                memset(&gbk[gbk_len], 0xFF, widget->size - gbk_len);
        
                memcpy(&buff[len], gbk, widget->size);
                len += widget->size;
            
            }break;
            
            default : break;
        }
    }

    if (len != 0)
    {
        result = dwin_var_write(head->addr, buff, len >> 1);
    }
    return result;
}

ret_t dwin_widget_event_register(dwin_widget_t* widget, uint32_t event, widget_event_func_t func)
{
    return_value_if_fail(widget, RET_BAD_PARAMS);
    return_value_if_fail(func, RET_BAD_PARAMS);

    widget->func = func;

    return RET_OK;
}
